package org.jeecg.modules.wflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.wflow.bean.do_.DeptDo;
import org.jeecg.modules.wflow.bean.do_.RoleDo;
import org.jeecg.modules.wflow.bean.do_.UserDeptDo;
import org.jeecg.modules.wflow.bean.do_.UserDo;
import org.jeecg.modules.wflow.bean.entity.WflowDepartments;
import org.jeecg.modules.wflow.bean.entity.WflowUserDepartments;
import org.jeecg.modules.wflow.bean.entity.WflowUserRoles;
import org.jeecg.modules.wflow.bean.entity.WflowUsers;
import org.jeecg.modules.wflow.bean.vo.ModelGroupVo;
import org.jeecg.modules.wflow.bean.vo.OrgTreeVo;
import org.jeecg.modules.wflow.mapper.*;
import org.jeecg.modules.wflow.service.OrgRepositoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 默认wflow的实现，集成自有系统需要自行实现接口
 * @author : willian fu
 * @date : 2022/11/29
 */
@Service("defaultOrgRepositoryService")
public class DefaultOrgRepositoryServiceImpl implements OrgRepositoryService {

    @Autowired
    private WflowUsersMapper usersMapper;

    @Autowired
    private WflowRolesMapper rolesMapper;

    @Autowired
    private WflowDepartmentsMapper departsMapper;

    @Autowired
    private WflowUserDepartmentsMapper userDepartmentsMapper;

    @Autowired
    private WflowUserRolesMapper userRolesMapper;

    @Autowired
    private WflowModelPermsMapper modelPermsMapper;

    @Override
    public List<ModelGroupVo.Form> getModelsByPerm(String userId) {
        return modelPermsMapper.selectByPerms(userId);
    }

    @Override
    public UserDo getUserById(String userId) {
        WflowUsers wflowUsers = usersMapper.selectById(userId);
        if (Objects.nonNull(wflowUsers)){
            UserDo userDo = new UserDo();
            BeanUtils.copyProperties(wflowUsers, userDo);
            return userDo;
        }
        return null;
    }

    @Override
    public List<OrgTreeVo> selectUsersByPy(String py) {
        return usersMapper.selectUsersByPy(py);
    }

    @Override
    public List<OrgTreeVo> selectUsersByDept(String deptId) {
        return usersMapper.selectUsersByDept(deptId);
    }

    @Override
    public List<UserDo> getUsersBatch(Collection<String> userIds) {
        try {
            return usersMapper.selectBatchIds(userIds).stream()
                    .map(u -> new UserDo(u.getUserId(), u.getUserName(), u.getAvatar()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public Set<String> getUsersByDepts(Collection<String> deptIds) {
        try {
            return userDepartmentsMapper.selectList(
                    new QueryWrapper<WflowUserDepartments>()
                            .select("user_id")
                            .in("dept_id", deptIds))
                    .stream().map(WflowUserDepartments::getUserId)
                    .collect(Collectors.toSet());
        } catch (Exception e) {
            return Collections.emptySet();
        }
    }

    @Override
    public DeptDo getDeptById(String deptId) {
        WflowDepartments departments = departsMapper.selectById(deptId);
        if (Objects.nonNull(departments)){
            DeptDo deptDo = new DeptDo();
            BeanUtils.copyProperties(departments, deptDo);
            return deptDo;
        }
        return null;
    }

    @Override
    public List<DeptDo> getSysAllDepts() {
        try {
            return departsMapper.selectList(null).stream()
                    .map(d -> new DeptDo(d.getId(), d.getDeptName(), d.getLeader(), d.getParentId()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public List<UserDeptDo> getSysAllUserDepts() {
        try {
            return userDepartmentsMapper.selectList(null).stream()
                    .map(d -> new UserDeptDo(d.getUserId(), d.getDeptId()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public List<OrgTreeVo> getSubDeptById(String parentId) {
        return departsMapper.selectByDept(parentId);
    }

    @Override
    public List<String> getRecursiveSubDept(String parentId) {
        List<String> list = new ArrayList<>();
        loadSubDept(parentId, list);
        return list;
    }

    /**
     * 递归加载所有子部门
     * @param parentId 父部门ID
     * @param subDepts 所有子部门缓存
     */
    private void loadSubDept(String parentId, List<String> subDepts){
        List<WflowDepartments> departments = departsMapper.selectList(
                new QueryWrapper<WflowDepartments>()
                .eq("parent_id", parentId));
        subDepts.addAll(departments.stream().map(WflowDepartments::getId).collect(Collectors.toList()));
        departments.forEach(d -> loadSubDept(d.getId(), subDepts));
    }

    @Override
    public List<RoleDo> getSysAllRoles() {
        try {
            return rolesMapper.selectList(null).stream()
                    .map(r -> new RoleDo(r.getRoleId(), r.getRoleName()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            return Collections.emptyList();
        }
    }

    @Override
    public Set<String> getUsersByRoles(List<String> roles) {
        return userRolesMapper.selectList(new QueryWrapper<WflowUserRoles>()
                        .select("user_id").in("role_id", roles)).stream()
                .map(WflowUserRoles::getUserId).collect(Collectors.toSet());
    }

    @Override
    public List<DeptDo> getDeptsByUser(String userId) {
        return userDepartmentsMapper.getUserDepts(userId);
    }
}
